from sc_engine.messaging import BaseMessage

class PlayerNameForced(BaseMessage):
    def __init__(self, player_id, forced_name):
        # int
        self.player_id = player_id

        # string
        self.forced_name = forced_name

class PlayerAliasForced(BaseMessage):
    def __init__(self, player_id, forced_alias):
        # int
        self.player_id = player_id

        # string
        self.forced_alias = forced_alias

class MapNameForced(BaseMessage):
    def __init__(self, map_id, forced_name):
        # int
        self.map_id = map_id

        # string
        self.forced_name = forced_name

class PlayerNameDetermination(BaseMessage):
    def __init__(self, player_id, true_name):
        # int
        self.player_id = player_id

        # string
        self.true_name = true_name

class PlayerAliasAddition(BaseMessage):
    def __init__(self, player_id, alias):
        # int
        self.player_id = player_id

        # string
        self.alias = alias

class PlayerDataRequested(BaseMessage):
    def __init__(self, player_id):
        # int
        self.player_id = player_id

class PlayerFetchRequested(BaseMessage):
    def __init__(self, player_id):
        # int
        self.player_id = player_id

class PlayerFetchAnnouncement(BaseMessage):
    def __init__(self, player_id, name, race):
        # int
        self.player_id = player_id

        # string
        self.name = name
        self.race = race

class PlayerFetchNonExistantPlayer(BaseMessage):
    def __init__(self, player_id):
        # int
        self.player_id = player_id

class PlayerDataAnnouncement(BaseMessage):
    ZERG = 'zerg'
    PROTOSS = 'protoss'
    TERRAN = 'terran'
    OTHER = 'other'

    def __init__(self, player_id, name, race, aliases):
        """
        Note: The name should not be included in the list of aliases
        """
        if race not in [self.ZERG, self.PROTOSS, self.TERRAN]:
            race = self.OTHER

        # int
        self.player_id = player_id

        # string
        self.name = name
        self.race = race

        # [string]
        self.aliases = aliases

    def from_race(self, protoss='protoss', terran='terran', zerg='zerg',
            other='other'):
        """
        Helper function, will the value of the argument depending on the
        player's race.
        """
        results = {
            self.ZERG : zerg,
            self.PROTOSS: protoss,
            self.TERRAN: terran,
            self.OTHER: other
        }

        return results[self.race]

class PlayerDoesNotExistAnnouncement(BaseMessage):
    def __init__(self, player_id):
        # int
        self.player_id = player_id

class TeamDataAnnouncement(BaseMessage):
    def __init__(self, team_id, name, aliases):
        """
        Note: The name should not be included in the list of aliases.
        """
        # int
        self.team_id = team_id

        # string
        self.name = name

        # [string]
        self.aliases = aliases

class MapFetchRequested(BaseMessage):
    def __init__(self, map_id):
        # int
        self.map_id = map_id

class MapFetchAnnouncement(BaseMessage):
    def __init__(self, map_id, name, version, width, height, image_filename):
        # int
        self.map_id = map_id

        # string
        self.name = name
        self.version = version

        # int
        self.width = width
        self.height = height

        # string
        self.image_filename = image_filename

class MapFetchNonExistantMap(BaseMessage):
    def __init__(self, map_id):
        # int
        self.map_id = map_id


class MapDataRequested(BaseMessage):
    def __init__(self, map_id):
        # int
        self.map_id = map_id

class MapDoesNotExistAnnouncement(BaseMessage):
    def __init__(self, map_id):
        # int
        self.map_id = map_id

class MapDataAnnouncement(BaseMessage):
    def __init__(self, map_id, name, version, width, height):
        # int
        self.map_id = map_id

        # string
        self.name = name
        self.version = version

        # int
        self.width = width
        self.height = height

class MapNameDetermination(BaseMessage):
    def __init__(self, map_id, true_name):
        # int
        self.map_id = map_id

        # string
        self.true_name = true_name

class LeagueDataTemplateAnnouncement(BaseMessage):
    def __init__(self, alias, name_key, name, stage_template,
            stage_known_dates, stage_aliases, stage_exceptions):
        # string
        self.alias = alias
        self.name_key = name_key
        self.name = name

        # [
        #   {
        #       stage_path: [string],
        #       name_key : string,
        #       name : string,
        #       format: {} or None
        #   }
        # ]
        self.stage_template = stage_template

        #
        # { datetime : [string] }
        #
        self.stage_known_dates = stage_known_dates

        # { string : [string] }
        self.stage_aliases = stage_aliases

        # { [string] : {same as stage_template's dict} }
        self.stage_exceptions = stage_exceptions

class LeagueDataAnnouncement(BaseMessage):
    def __init__(self, name_key, name, alias):
        # string
        self.name_key = name_key
        self.name = name
        self.alias = alias

class LeagueStagePathDateRequested(BaseMessage):
    def __init__(self, league, stage, date):
        # string
        self.league = league
        self.stage = stage

        # datetime
        self.date = date
    
class LeagueStagePathDateAnnouncement(BaseMessage):
    def __init__(self, league, stage_path, date):
        # string
        self.league = league

        # [string]
        self.stage_path = stage_path

        # datetime
        self.date = date

class LeagueStageDataAnnouncement(BaseMessage):
    def __init__(self, league, stage_path, name, start_date, end_date, format):
        # string
        self.league = league

        # [string]
        self.stage_path = stage_path

        # string
        self.name = name

        # datetime
        self.start_date = start_date
        self.end_date = end_date

        # { number_of_games = int } or None
        self.format = format

class ProleagueFetchRequested(BaseMessage):
    def __init__(self, date):
        # datetime
        self.date = date

class ProleagueMatchFetchAnnouncement(BaseMessage):
    def __init__(self, league, stage, team_one, team_two, date_played,
            winner, winner_score, loser_score):
        # string
        self.league = league
        self.stage = stage

        # string
        self.team_one = team_one
        self.team_two = team_two

        # datetime
        self.date_played = date_played

        # string
        self.winner = winner

        # int or None
        self.winner_score = winner_score
        self.loser_score = loser_score

class ProleagueGameFetchAnnouncement(BaseMessage):
    def __init__(self, league, stage, team_one, team_two, date_played, 
            game_number, game_map,
            player_one, player_one_start_location,
            player_two, player_two_start_location,
            winner, playtime):

        # string
        self.league = league
        self.stage = stage

        # datetime
        self.date_played = date_played

        # string
        self.team_one = team_one
        self.team_two = team_two

        # int
        self.game_number = game_number
        self.game_map = game_map
        self.player_one = player_one
        self.player_two = player_two

        # int or None
        self.player_one_start_location = player_one_start_location
        self.player_two_start_location = player_two_start_location
        
        self.winner = winner
        
        # timedelta or None
        self.playtime = playtime


class ProleagueMatchParseAnnouncement(BaseMessage):
    def __init__(self, league, stage_path, team_one, team_two,
            winner, winner_score, loser_score):

        # string
        self.league = league

        # [string]
        self.stage_path = stage_path

        # int or None
        self.team_one = team_one
        self.team_two = team_two
        self.winner = winner
        self.winner_score = winner_score
        self.loser_score = loser_score

class ProleagueGameParseAnnouncement(BaseMessage):
    def __init__(self, league, stage_path, team_one, team_two,
            date_played, game_number, game_map, 
            player_one, player_one_start_location,
            player_two, player_two_start_location,
            winner, playtime):

        # string
        self.league = league

        # [string]
        self.stage_path = stage_path

        # int or None
        self.team_one = team_one
        self.team_two = team_two

        # datetime
        self.date_played = date_played

        # int
        self.game_number = game_number
        self.game_map = game_map
        self.player_one = player_one
        self.player_two = player_two

        # int or None
        self.player_one_start_location = player_one_start_location
        self.player_two_start_location = player_two_start_location
        
        self.winner = winner
        
        # timedelta or None
        self.playtime = playtime

class ProleagueMatchIdAnnouncement(BaseMessage):
    def __init__(self, match_id, league, stage_path, team_one, team_two):
        # int
        self.match_id = match_id

        # string
        self.league = league

        # [string]
        self.stage_path = stage_path
        
        # int
        self.team_one = team_one
        self.team_two = team_two

class ProleagueMatchDataAnnouncement(BaseMessage):
    def __init__(self, match_id, winner, winner_score, loser_score):
        # int
        self.match_id = match_id

        # int
        self.winner = winner
        self.winner_score = winner_score
        self.loser_score = loser_score

class GameDataAnnouncement(BaseMessage):
    def __init__(self, match_id, date_played, game_number, game_map,
            player_one, player_one_start_location,
            player_two, player_two_start_location,
            winner, playtime):

        # int
        self.match_id = match_id

        # datetime
        self.date_played = date_played

        # int
        self.game_number = game_number
        self.game_map = game_map

        self.player_one = player_one
        self.player_two = player_two

        # int or None
        self.player_one_start_location = player_one_start_location
        self.player_two_start_location = player_two_start_location
        
        self.winner = winner
        
        # timedelta or None
        self.playtime = playtime

class YouTubeVideoFetchRequested(BaseMessage):
    def __init__(self, video_id):
        # string
        self.video_id = video_id

class YouTubeFetchRequested(BaseMessage):
    def __init__(self, start_date, end_date):
        # datetime
        self.start_date = start_date
        self.end_date = end_date

class YouTubeAuthorFetchRequested(BaseMessage):
    def __init__(self, author, start_date, end_date):
        # string
        self.author = author

        # datetime
        self.start_date = start_date
        self.end_date = end_date

class YouTubeAuthorQueryFetchRequested(BaseMessage):
    def __init__(self, author, query):
        # string
        self.author = author
        self.query = query

class YouTubeFetchAnnouncement(BaseMessage):
    def __init__(self, video_id, title, description, author, published_date):
        # string
        self.video_id = video_id
        self.title = title
        self.description = description
        self.author = author

        # datetime
        self.published_date = published_date

class YouTubeParseAnnouncement(BaseMessage):
    def __init__(self, video_id, title, author, part_number,
            date_played, teams, players, game_number):
        # string
        self.video_id = video_id
        self.title = title
        self.author = author

        # [int]
        self.part_number = part_number

        # [datetime]
        self.date_played = date_played

        # [int]
        self.teams = teams
        self.players = players
        self.game_number = game_number

class YouTubePartialParseAnnouncement(BaseMessage):
    def __init__(self, video_id, title, date_played, teams, players, game_number, possible_results):
        # string
        self.video_id = video_id
        self.title = title

        # [datetime]
        self.date_played = date_played

        # [int]
        self.teams = teams
        self.players = players
        self.game_number = game_number

        # [
        #   {
        #       league:         string
        #       stage_path:     string
        #       date_played:    datetime
        #       team_one:       int
        #       team_two:       int
        #       player_one:     int
        #       player_two:     int
        #       game_number:    int
        #   }
        # ]
        self.possible_results = possible_results

class ManualProleagueYouTubeLinkAnnouncement(BaseMessage):
    def __init__(self, video_id, part_number,
            league, stage_path, team_one, team_two, game_number):

        # string
        self.video_id = video_id
        self.part_number = part_number

        self.league = league
        self.stage_path = stage_path

        # int
        self.team_one = team_one
        self.team_two = team_two
        self.game_number = game_number

class ManualYouTubeLinkAnnouncement(BaseMessage):
    def __init__(self, video_id, part_number, match_id, game_number):
        # string
        self.video_id = video_id

        # int
        self.part_number = part_number
        self.match_id = match_id
        self.game_number = game_number


class VideoGameLinkAnnouncement(BaseMessage):
    def __init__(self, match_id, game_number, video_id, author, part_number):

        # int
        self.match_id = match_id
        self.game_number = game_number

        # string
        self.video_id = video_id
        self.author = author

        # int
        self.part_number = part_number


class CommentarySetDataAnnouncement(BaseMessage):
    def __init__(self, match_id, game_number, author, video_ids):

        # int
        self.match_id = match_id
        self.game_number = game_number

        # string
        self.author = author

        # [string]
        self.video_ids = video_ids


